﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;

namespace WowGuildSite.Armory
{
    public enum CharacterClass
    {        
        Warrior     = 1,
        Paladin     = 2,
        Hunter      = 3,
        Rogue       = 4,   
        Priest      = 5,    
        Shaman      = 7,
        Mage        = 8,   
        Warlock     = 9,
        Druid       = 11
    }

    public enum CharacterRace
    {
        Human       = 1,
        Orc         = 2,
        Dwarf       = 3,
        Nightelf    = 4,
        Undead      = 5,
        Tauren      = 6,
        Gnome       = 7,
        Troll       = 8,
        Bloodelf    = 10,
        Draenei     = 11,
    }

    public enum CharacterGender
    {
        Male        = 0,
        Female      = 1,
    }

    public enum CharacterFaction
    {
        Alliance    = 0,
        Horde       = 1,
    }

    public class ArmoryCharacter : ArmoryBase
    {        
        private string                      name;

        private ArmoryXmlDocument           sheetDocument;
        private ArmoryXmlDocument           talentDocument;

        private ArmorySkillCollection       skills;
        private ArmoryReputationCollection  reputations;
        private ArmorySpellStats            spellStats;
        private ArmoryBaseStatCollection    baseStats;
        private ArmoryResistanceStats       resistanceStats;
        private ArmoryMeleeStats            meleeStats;
        private ArmoryRangedStats           rangedStats;
        private ArmoryDefenseStats          defenseStats;

        public string                       Name
        {
            get
            {
                return name;
            }
        }

        public ArmoryGuild                  Guild
        {
            get
            {
                string guildName = sheetDocument.GetAttributeText("/page/characterInfo/character/@guildName");
                if (!string.IsNullOrEmpty(guildName))
                {
                    return Accessor.GetGuild(guildName);
                }
                return null;
            }
        }

        public int                          GuildRank
        {
            get
            {
                if (Guild != null)
                {
                    return Guild.GetGuildRank(name);
                }
                return 0;
            }
        }

        public string                       LocalizedGuildRank
        {
            get
            {
                string rank = Accessor.GuildRanks[GuildRank] as string;
                if ( rank == null )
                {
                    return GuildRank.ToString();
                }
                else
                {
                    return rank;
                }
            }
        }

        public CharacterClass               Class
        {
            get
            {
                return (CharacterClass)sheetDocument.GetAttributeInt("/page/characterInfo/character/@classId");
            }
        }

        public ArmoryIcon                   ClassIcon
        {
            get
            {
                return Accessor.GetIcon(IconType.Class, Class);
            }
        }

        public string                       LocalizedClass
        {
            get
            {
                return sheetDocument.GetAttributeText("/page/characterInfo/character/@class");
            }
        }

        public CharacterRace                Race
        {
            get
            {
                return (CharacterRace)sheetDocument.GetAttributeInt("/page/characterInfo/character/@raceId");
            }
        }

        public ArmoryIcon                   RaceIcon
        {
            get
            {
                return Accessor.GetIcon(IconType.Race, Race);
            }
        }

        public string                       LocalizedRace
        {
            get
            {
                return sheetDocument.GetAttributeText("/page/characterInfo/character/@race");
            }
        }

        public CharacterGender              Gender
        {
            get
            {
                return (CharacterGender)sheetDocument.GetAttributeInt("/page/characterInfo/character/@genderId");
            }
        }

        public ArmoryIcon                   GenderIcon
        {
            get
            {
                return Accessor.GetIcon(IconType.Gender, Gender);
            }
        }

        public string                       LocalizedGender
        {
            get
            {
                return sheetDocument.GetAttributeText("page/characterInfo/character/@gender");
            }
        }

        public CharacterFaction             Faction
        {
            get
            {
                return (CharacterFaction)sheetDocument.GetAttributeInt("/page/characterInfo/character/@factionId");
            }
        }

        public ArmoryIcon                   FactionIcon
        {
            get
            {
                return Accessor.GetIcon(IconType.Faction, Faction);
            }
        }

        public string                       LocalizedFaction
        {
            get
            {
                return sheetDocument.GetAttributeText("/page/characterInfo/character/@faction");
            }
        }

        public int                          Level
        {
            get
            {
                return sheetDocument.GetAttributeInt("/page/characterInfo/character/@level");
            }
        }

        public int[]                        TalentTreePoints
        {
            get
            {
                int[] result = new int[3];
                result[0] = sheetDocument.GetAttributeInt("/page/characterInfo/characterTab/talentSpec/@treeOne");
                result[1] = sheetDocument.GetAttributeInt("/page/characterInfo/characterTab/talentSpec/@treeTwo");
                result[2] = sheetDocument.GetAttributeInt("/page/characterInfo/characterTab/talentSpec/@treeThree");

                return result;
            }
        }

        public ArmoryBar                    HealthBar
        {
            get
            {   
                return ArmoryBar.FromElement( sheetDocument.GetElement("/page/characterInfo/characterTab/characterBars/health") );
            }
        }

        public ArmoryBar                    SecondaryBar
        {
            get
            {
                return ArmoryBar.FromElement(sheetDocument.GetElement("/page/characterInfo/characterTab/characterBars/secondBar") );
            }
        }

        public ArmorySkillCollection        Skills
        {
            get
            {
                return skills;
            }
        }

        public ArmoryReputationCollection   Reputation
        {
            get
            {
                return reputations;
            }
        }

        public ArmorySpellStats             SpellStats
        {
            get
            {
                return spellStats;
            }
        }

        public ArmoryBaseStatCollection     BaseStats
        {
            get
            {
                return baseStats;
            }
        }

        public ArmoryResistanceStats        ResistanceStats
        {
            get
            {
                return resistanceStats;
            }
        }

        public ArmoryMeleeStats             MeleeStats
        {
            get
            {
                return meleeStats;
            }
        }

        public ArmoryRangedStats            RangedStats
        {
            get
            {
                return rangedStats;
            }
        }

        public ArmoryDefenseStats           DefenseStats
        {
            get
            {
                return defenseStats;
            }
        }

        internal ArmoryXmlDocument          SheetDocument
        {
            get { return sheetDocument; }
        }

        internal ArmoryCharacter(    ArmoryAccessor accessor,
                                    string name )
            : base(accessor)
        {
            if (string.IsNullOrEmpty(name))
            {
                throw new ArgumentNullException("name");
            }

            this.name               = name;

            this.sheetDocument      = new ArmoryXmlDocument(delegate() { return Accessor.DataSource.GetCharacterSheetData(name); });
            this.talentDocument     = new ArmoryXmlDocument(delegate() { return Accessor.DataSource.GetCharacterTalentData(name); });

            skills          = new ArmorySkillCollection(this);
            reputations     = new ArmoryReputationCollection(this);
            spellStats      = new ArmorySpellStats(this);
            baseStats       = new ArmoryBaseStatCollection(this);
            resistanceStats = new ArmoryResistanceStats(this);
            meleeStats      = new ArmoryMeleeStats(this);
            rangedStats     = new ArmoryRangedStats(this);
            defenseStats    = new ArmoryDefenseStats(this);
        }
    }
}
